package com.czz.ucenter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.czz.common.exception.CustomerException;
import com.czz.common.exception.ResultCodeEnum;
import com.czz.ucenter.client.OssClient;
import com.czz.ucenter.client.SmsClient;
import com.czz.ucenter.entity.User;
import com.czz.ucenter.mapper.UserMapper;
import com.czz.ucenter.service.UserService;
import com.czz.ucenter.utils.CodecUtils;
import com.czz.ucenter.utils.NumberUtils;
import com.czz.ucenter.vo.UserVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

/**
 * @ClassName: UserServiceImpl
 * @Author Czz
 * @Date 2019/12/11
 * @Time 10:54
 **/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    UserMapper userMapper;

    @Autowired
    OssClient ossClient;

    @Autowired
    SmsClient smsClient;

    @Autowired
    private StringRedisTemplate redisTemplate;

    static final String SMS_PREFIX = "user:code:phone:";

    @Override
    public Boolean register(User user, String code) {
        //判断手机号是否注册
        User temp = userMapper.selectOne(new QueryWrapper<User>().eq("user_mobile", user.getMobile()));

        if (!ObjectUtils.isEmpty(temp)){
            throw new CustomerException(ResultCodeEnum.MOBILE_EXISTS);
        }

        //检验短信验证码
        String cacheCode = this.redisTemplate.opsForValue().get(SMS_PREFIX + user.getMobile());
        if (!org.apache.commons.lang3.StringUtils.equals(code, cacheCode)) {
            return false;
        }

        //生成salt
        String salt = CodecUtils.generateSalt();
        user.setSalt(salt);

        //加密密码
        user.setPassword(CodecUtils.md5Hex(user.getPassword(),salt));

        //设置默认项
        user.setNickname("用户"+NumberUtils.generateCode(8));
        user.setAvatar("https://czz-education.oss-cn-shenzhen.aliyuncs.com/avatar/default.jpg");

        //添加到数据库
        int result = userMapper.insert(user);
        if (result > 0){
            this.redisTemplate.delete(SMS_PREFIX + user.getMobile());
            return true;
        }
        return false;
    }

    @Override
    public Boolean check(String mobile) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
        queryWrapper.eq("user_mobile",mobile);
        Integer result = userMapper.selectCount(queryWrapper);
        return (result>0) ? false : true;
    }

    @Override
    public User login(String username, String password, Boolean teacher) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<User>();

        //检验手机号
        queryWrapper.eq("user_mobile",username);
        User user = userMapper.selectOne(queryWrapper);

        if (ObjectUtils.isEmpty(user)){
            return null;
        }

        //判断是否为讲师
        if (teacher){
            if (user.getTeacher().equals(0)){
                return null;
            }
        }
        //检验密码
        if (!user.getPassword().equals(CodecUtils.md5Hex(password,user.getSalt()))){
            return null;
        }

        //检验通过
        //判断用户是否禁用
        if (user.getStatus().equals(1)){
            throw new CustomerException(ResultCodeEnum.USER_BAN);
        }
        return user;
    }

    @Override
    public UserVo getUserById(String id) {
        User user = userMapper.selectById(id);

        //处理手机号码为保密
        user.setMobile(user.getMobile().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user,userVo);
        return userVo;
    }

    @Override
    public void cancelAvatarUpload(String avatar) {
        String OSS_URL = "http://czz-education.oss-cn-shenzhen.aliyuncs.com/";
        String avatarUrl = avatar.replace(OSS_URL,"").replaceAll("/","&&");
        ossClient.deleteOssFile(avatarUrl).getMessage();
    }

    @Override
    public void sendVerifyCode(String phone) {
        try {
            //生成验证码
            String code = NumberUtils.generateCode(6);

            //发送短信
            smsClient.sendUserSms(phone,code);

            //验证码存入redis
            this.redisTemplate.opsForValue().set(SMS_PREFIX + phone, code, 5, TimeUnit.MINUTES);
        }
        catch (Exception e){
            e.printStackTrace();
            throw new CustomerException(ResultCodeEnum.SEND_SMS_ERROR);
        }
    }

    @Override
    public Integer checkCode(String phone,String code) {
        //根据验证码token判断redis中是否存在该验证码，如不存在则返回验证码过期
        String redisToken = this.redisTemplate.opsForValue().get(SMS_PREFIX + phone);
        if (StringUtils.isEmpty(redisToken)){
            return 1;
        }

        //存在验证码，但对比不一致，则返回验证码错误
        if (!code.equals(redisToken)){
            return 2;
        }
        //对比一致，返回验证码成功
        else {
            return 0;
        }
    }

    @Override
    public void updatePassword(String id,String oldPassword, String newPassword) {
        User user = userMapper.selectById(id);

        //判断密码是否正确
        if (!user.getPassword().equals(CodecUtils.md5Hex(oldPassword,user.getSalt()))){
            throw new CustomerException(ResultCodeEnum.USERNAME_OR_PASSWORD_ERROR);
        }

        user.setPassword(CodecUtils.md5Hex(newPassword,user.getSalt()));
        userMapper.updateById(user);
    }

    @Override
    public void updateUserById(User user) {
        User temp = userMapper.selectById(user.getId());

        if (temp.getNickname().equals(user.getNickname())){
            user.setNickname(null);
        }

        if (temp.getEmail().equals(user.getEmail())){
            user.setEmail(null);
        }

        Integer result = 0;

        //判断昵称是否唯一
        QueryWrapper<User> queryWrapper1 = new QueryWrapper<User>();
        queryWrapper1.eq("user_nickname",user.getNickname());
        result = userMapper.selectCount(queryWrapper1);
        if (result > 0) {
            throw new CustomerException(ResultCodeEnum.NICKNAME_EXISTS);
        }

        //判断邮箱是否唯一
        QueryWrapper<User> queryWrapper2 = new QueryWrapper<User>();
        queryWrapper2.eq("user_email",user.getEmail());
        result = userMapper.selectCount(queryWrapper2);
        if (result > 0) {
            throw new CustomerException(ResultCodeEnum.EMAIL_EXISTS);
        }

        userMapper.updateById(user);
    }

}
